[iOS 8] Swift で NSNotification の userInfo を扱う
Swift で NSNotification の userInfo を扱う
個人的にハマったので情報共有。
Swift で NSNotification の userInfo を使おうと思った場合、Objective-C ほど簡単には扱えません。
userInfo の型は次のようになっているので、Optional Value やら AnyObject やらで、アンラップしたりキャストしたりする必要があります。
class NSNotification : NSObject, NSCopying, NSCoding { // ... var userInfo: [NSObject : AnyObject]? { get } // ... }
色々調べて試した結果、次の2通りのパターンのどちらかを使うのがいいのではないかと思いました。
- 変数宣言時にアンラップ & キャストする
- Value-Binding 時にアンラップ & キャストする
サンプルコード
1. 変数宣言時にアンラップ & キャストする
if let userInfo = notification.userInfo { let value = userInfo["number"]! as Int let plus10 = value + 10 println(plus10) }
2. Value-Binding 時にアンラップ & キャストする
if let userInfo = notification.userInfo as [String: Int]! { let value = userInfo["number"]! let plus10 = value + 10 println(plus10) }
私はアンラップが1回で済むので、前者のほうが好きです。
また、次のように短く書くこともできますが、userInfo が nil の場合にランタイムエラーとなるので、あまりオススメはしません。
let value = notification.userInfo!["number"]! as Int let plus10 = value + 10 println(plus10)
フルサンプルコード
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let nc = NSNotificationCenter.defaultCenter() // 登録 nc.addObserver(self, selector: "handleTestNotification:", name: "testNotification", object: nil) // 通知 nc.postNotificationName("testNotification", object: nil, userInfo: ["number": 100]) } func handleTestNotification(notification: NSNotification) { // 変数宣言時にアンラップ & キャストする方法 if let userInfo = notification.userInfo { let value = userInfo["number"]! as Int let plus10 = value + 10 println(plus10) } // Value-Binding 時にアンラップ & キャストする方法 if let userInfo = notification.userInfo as [String: Int]! { let value = userInfo["number"]! let plus10 = value + 10 println(plus10) } // 1行で書く方法。ただしuserInfoがnilの場合はランタイムエラー let value = notification.userInfo!["number"]! as Int let plus10 = value + 10 println(plus10) } }
まとめ
Swift は type safe な言語になっているため、Objective-C よりも細かく型を意識しなければなりません。
はじめは少し難しいですが、一つ一つ身につけていきましょう。